﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x02000054 RID: 84
	[HelpURL("https://www.youtube.com/watch?v=r5jiZnsDH3M")]
	[AddComponentMenu("Scripts/RootMotion.FinalIK/Interaction System/Interaction Object")]
	public class InteractionObject : MonoBehaviour
	{
		// Token: 0x060003CF RID: 975 RVA: 0x0000490A File Offset: 0x00002B0A
		[ContextMenu("TUTORIAL VIDEO (PART 1: BASICS)")]
		public void OpenTutorial1()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=r5jiZnsDH3M");
		}

		// Token: 0x060003D0 RID: 976 RVA: 0x00004916 File Offset: 0x00002B16
		[ContextMenu("TUTORIAL VIDEO (PART 2: PICKING UP...)")]
		public void OpenTutorial2()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=eP9-zycoHLk");
		}

		// Token: 0x060003D1 RID: 977 RVA: 0x00004922 File Offset: 0x00002B22
		[ContextMenu("TUTORIAL VIDEO (PART 3: ANIMATION)")]
		public void OpenTutorial3()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=sQfB2RcT1T4&index=14&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
		}

		// Token: 0x060003D2 RID: 978 RVA: 0x0000492E File Offset: 0x00002B2E
		[ContextMenu("TUTORIAL VIDEO (PART 4: TRIGGERS)")]
		public void OpenTutorial4()
		{
			Application.OpenURL("https://www.youtube.com/watch?v=-TDZpNjt2mk&index=15&list=PLVxSIA1OaTOu8Nos3CalXbJ2DrKnntMv6");
		}

		// Token: 0x060003D3 RID: 979 RVA: 0x00002E24 File Offset: 0x00001024
		[ContextMenu("Support Group")]
		public void SupportGroup()
		{
			Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
		}

		// Token: 0x060003D4 RID: 980 RVA: 0x00002E30 File Offset: 0x00001030
		[ContextMenu("Asset Store Thread")]
		public void ASThread()
		{
			Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
		}

		// Token: 0x17000057 RID: 87
		// (get) Token: 0x060003D5 RID: 981 RVA: 0x0000493A File Offset: 0x00002B3A
		// (set) Token: 0x060003D6 RID: 982 RVA: 0x00004942 File Offset: 0x00002B42
		public float length { get; set; }

		// Token: 0x17000058 RID: 88
		// (get) Token: 0x060003D7 RID: 983 RVA: 0x0000494B File Offset: 0x00002B4B
		// (set) Token: 0x060003D8 RID: 984 RVA: 0x00004953 File Offset: 0x00002B53
		public InteractionSystem lastUsedInteractionSystem { get; set; }

		// Token: 0x060003D9 RID: 985 RVA: 0x0002D88C File Offset: 0x0002BA8C
		public void Initiate()
		{
			for (int i = 0; i < this.weightCurves.Length; i++)
			{
				if (this.weightCurves[i].curve.length > 0)
				{
					float time = this.weightCurves[i].curve.keys[this.weightCurves[i].curve.length - 1].time;
					this.length = Mathf.Clamp(this.length, time, this.length);
				}
			}
			for (int j = 0; j < this.events.Length; j++)
			{
				this.length = Mathf.Clamp(this.length, this.events[j].time, this.length);
			}
			this.targets = this.targetsRoot.GetComponentsInChildren<InteractionTarget>();
		}

		// Token: 0x17000059 RID: 89
		// (get) Token: 0x060003DA RID: 986 RVA: 0x0000495C File Offset: 0x00002B5C
		public Transform lookAtTarget
		{
			get
			{
				if (this.otherLookAtTarget != null)
				{
					return this.otherLookAtTarget;
				}
				return base.transform;
			}
		}

		// Token: 0x060003DB RID: 987 RVA: 0x0000497C File Offset: 0x00002B7C
		public InteractionTarget[] GetTargets()
		{
			return this.targets;
		}

		// Token: 0x060003DC RID: 988 RVA: 0x0002D964 File Offset: 0x0002BB64
		public Transform GetTarget(FullBodyBipedEffector effectorType, string tag)
		{
			if (tag == string.Empty || tag == string.Empty)
			{
				return this.GetTarget(effectorType);
			}
			for (int i = 0; i < this.targets.Length; i++)
			{
				if (this.targets[i].effectorType == effectorType && this.targets[i].tag == tag)
				{
					return this.targets[i].transform;
				}
			}
			return base.transform;
		}

		// Token: 0x060003DD RID: 989 RVA: 0x00004984 File Offset: 0x00002B84
		public void OnStartInteraction(InteractionSystem interactionSystem)
		{
			this.lastUsedInteractionSystem = interactionSystem;
		}

		// Token: 0x060003DE RID: 990 RVA: 0x0002D9F4 File Offset: 0x0002BBF4
		public void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, InteractionTarget target, float timer, float weight)
		{
			for (int i = 0; i < this.weightCurves.Length; i++)
			{
				float num = (!(target == null)) ? target.GetValue(this.weightCurves[i].type) : 1f;
				this.Apply(solver, effector, this.weightCurves[i].type, this.weightCurves[i].GetValue(timer), weight * num);
			}
			for (int j = 0; j < this.multipliers.Length; j++)
			{
				if (this.multipliers[j].curve == this.multipliers[j].result && !Warning.logged)
				{
					Warning.Log("InteractionObject Multiplier 'Curve' " + this.multipliers[j].curve.ToString() + "and 'Result' are the same.", base.transform, false);
				}
				int weightCurveIndex = this.GetWeightCurveIndex(this.multipliers[j].curve);
				if (weightCurveIndex != -1)
				{
					float num2 = (!(target == null)) ? target.GetValue(this.multipliers[j].result) : 1f;
					this.Apply(solver, effector, this.multipliers[j].result, this.multipliers[j].GetValue(this.weightCurves[weightCurveIndex], timer), weight * num2);
				}
				else if (!Warning.logged)
				{
					Warning.Log("InteractionObject Multiplier curve " + this.multipliers[j].curve.ToString() + "does not exist.", base.transform, false);
				}
			}
		}

		// Token: 0x060003DF RID: 991 RVA: 0x0002DB98 File Offset: 0x0002BD98
		public float GetValue(InteractionObject.WeightCurve.Type weightCurveType, InteractionTarget target, float timer)
		{
			int weightCurveIndex = this.GetWeightCurveIndex(weightCurveType);
			if (weightCurveIndex != -1)
			{
				float num = (!(target == null)) ? target.GetValue(weightCurveType) : 1f;
				return this.weightCurves[weightCurveIndex].GetValue(timer) * num;
			}
			for (int i = 0; i < this.multipliers.Length; i++)
			{
				if (this.multipliers[i].result == weightCurveType)
				{
					int weightCurveIndex2 = this.GetWeightCurveIndex(this.multipliers[i].curve);
					if (weightCurveIndex2 != -1)
					{
						float num2 = (!(target == null)) ? target.GetValue(this.multipliers[i].result) : 1f;
						return this.multipliers[i].GetValue(this.weightCurves[weightCurveIndex2], timer) * num2;
					}
				}
			}
			return 0f;
		}

		// Token: 0x1700005A RID: 90
		// (get) Token: 0x060003E0 RID: 992 RVA: 0x0000498D File Offset: 0x00002B8D
		public Transform targetsRoot
		{
			get
			{
				if (this.otherTargetsRoot != null)
				{
					return this.otherTargetsRoot;
				}
				return base.transform;
			}
		}

		// Token: 0x060003E1 RID: 993 RVA: 0x000049AD File Offset: 0x00002BAD
		public void Awake()
		{
			this.Initiate();
		}

		// Token: 0x060003E2 RID: 994 RVA: 0x0002DC74 File Offset: 0x0002BE74
		public void Apply(IKSolverFullBodyBiped solver, FullBodyBipedEffector effector, InteractionObject.WeightCurve.Type type, float value, float weight)
		{
			switch (type)
			{
			case InteractionObject.WeightCurve.Type.PositionWeight:
				solver.GetEffector(effector).positionWeight = Mathf.Lerp(solver.GetEffector(effector).positionWeight, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.RotationWeight:
				solver.GetEffector(effector).rotationWeight = Mathf.Lerp(solver.GetEffector(effector).rotationWeight, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.PositionOffsetX:
				solver.GetEffector(effector).position += ((!(this.positionOffsetSpace != null)) ? solver.GetRoot().rotation : this.positionOffsetSpace.rotation) * Vector3.right * value * weight;
				return;
			case InteractionObject.WeightCurve.Type.PositionOffsetY:
				solver.GetEffector(effector).position += ((!(this.positionOffsetSpace != null)) ? solver.GetRoot().rotation : this.positionOffsetSpace.rotation) * Vector3.up * value * weight;
				return;
			case InteractionObject.WeightCurve.Type.PositionOffsetZ:
				solver.GetEffector(effector).position += ((!(this.positionOffsetSpace != null)) ? solver.GetRoot().rotation : this.positionOffsetSpace.rotation) * Vector3.forward * value * weight;
				return;
			case InteractionObject.WeightCurve.Type.Pull:
				solver.GetChain(effector).pull = Mathf.Lerp(solver.GetChain(effector).pull, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.Reach:
				solver.GetChain(effector).reach = Mathf.Lerp(solver.GetChain(effector).reach, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.Push:
				solver.GetChain(effector).push = Mathf.Lerp(solver.GetChain(effector).push, value, weight);
				return;
			case InteractionObject.WeightCurve.Type.PushParent:
				solver.GetChain(effector).pushParent = Mathf.Lerp(solver.GetChain(effector).pushParent, value, weight);
				return;
			}
		}

		// Token: 0x060003E3 RID: 995 RVA: 0x0002DE98 File Offset: 0x0002C098
		public Transform GetTarget(FullBodyBipedEffector effectorType)
		{
			for (int i = 0; i < this.targets.Length; i++)
			{
				if (this.targets[i].effectorType == effectorType)
				{
					return this.targets[i].transform;
				}
			}
			return base.transform;
		}

		// Token: 0x060003E4 RID: 996 RVA: 0x0002DEE8 File Offset: 0x0002C0E8
		public int GetWeightCurveIndex(InteractionObject.WeightCurve.Type weightCurveType)
		{
			for (int i = 0; i < this.weightCurves.Length; i++)
			{
				if (this.weightCurves[i].type == weightCurveType)
				{
					return i;
				}
			}
			return -1;
		}

		// Token: 0x060003E5 RID: 997 RVA: 0x0002DF24 File Offset: 0x0002C124
		public int GetMultiplierIndex(InteractionObject.WeightCurve.Type weightCurveType)
		{
			for (int i = 0; i < this.multipliers.Length; i++)
			{
				if (this.multipliers[i].result == weightCurveType)
				{
					return i;
				}
			}
			return -1;
		}

		// Token: 0x060003E6 RID: 998 RVA: 0x000049B5 File Offset: 0x00002BB5
		[ContextMenu("User Manual")]
		public void OpenUserManual()
		{
			Application.OpenURL("http://www.root-motion.com/finalikdox/html/page10.html");
		}

		// Token: 0x060003E7 RID: 999 RVA: 0x000049C1 File Offset: 0x00002BC1
		[ContextMenu("Scrpt Reference")]
		public void OpenScriptReference()
		{
			Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_interaction_object.html");
		}

		// Token: 0x04000288 RID: 648
		[Tooltip("If the Interaction System has a 'Look At' LookAtIK component assigned, will use it to make the character look at the specified Transform. If unassigned, will look at this GameObject.")]
		public Transform otherLookAtTarget;

		// Token: 0x04000289 RID: 649
		[Tooltip("The root Transform of the InteractionTargets. If null, will use this GameObject. GetComponentsInChildren<InteractionTarget>() will be used at initiation to find all InteractionTargets associated with this InteractionObject.")]
		public Transform otherTargetsRoot;

		// Token: 0x0400028A RID: 650
		[Tooltip("If assigned, all PositionOffset channels will be applied in the rotation space of this Transform. If not, they will be in the rotation space of the character.")]
		public Transform positionOffsetSpace;

		// Token: 0x0400028B RID: 651
		[Tooltip("The weight curves for the interaction.")]
		public InteractionObject.WeightCurve[] weightCurves;

		// Token: 0x0400028C RID: 652
		[Tooltip("The weight curve multipliers for the interaction.")]
		public InteractionObject.Multiplier[] multipliers;

		// Token: 0x0400028D RID: 653
		[Tooltip("The interaction events.")]
		public InteractionObject.InteractionEvent[] events;

		// Token: 0x0400028E RID: 654
		public InteractionTarget[] targets = new InteractionTarget[0];

		// Token: 0x02000055 RID: 85
		[Serializable]
		public class InteractionEvent
		{
			// Token: 0x060003E9 RID: 1001 RVA: 0x0002DF60 File Offset: 0x0002C160
			public void Activate(Transform t)
			{
				foreach (InteractionObject.AnimatorEvent animatorEvent in this.animations)
				{
					animatorEvent.Activate(this.pickUp);
				}
				foreach (InteractionObject.Message message in this.messages)
				{
					message.Send(t);
				}
			}

			// Token: 0x04000291 RID: 657
			[Tooltip("The time of the event since interaction start.")]
			public float time;

			// Token: 0x04000292 RID: 658
			[Tooltip("If true, the interaction will be paused on this event. The interaction can be resumed by InteractionSystem.ResumeInteraction() or InteractionSystem.ResumeAll;")]
			public bool pause;

			// Token: 0x04000293 RID: 659
			[Tooltip("If true, the object will be parented to the effector bone on this event. Note that picking up like this can be done by only a single effector at a time. If you wish to pick up an object with both hands, see the Interaction PickUp2Handed demo scene.")]
			public bool pickUp;

			// Token: 0x04000294 RID: 660
			[Tooltip("The animations called on this event.")]
			public InteractionObject.AnimatorEvent[] animations;

			// Token: 0x04000295 RID: 661
			[Tooltip("The messages sent on this event using GameObject.SendMessage().")]
			public InteractionObject.Message[] messages;
		}

		// Token: 0x02000056 RID: 86
		[Serializable]
		public class Message
		{
			// Token: 0x060003EB RID: 1003 RVA: 0x0002DFC8 File Offset: 0x0002C1C8
			public void Send(Transform t)
			{
				if (this.recipient == null)
				{
					return;
				}
				if (this.function == string.Empty || this.function == string.Empty)
				{
					return;
				}
				this.recipient.SendMessage(this.function, t, SendMessageOptions.RequireReceiver);
			}

			// Token: 0x04000296 RID: 662
			public const string empty = "";

			// Token: 0x04000297 RID: 663
			[Tooltip("The name of the function called.")]
			public string function;

			// Token: 0x04000298 RID: 664
			[Tooltip("The recipient game object.")]
			public GameObject recipient;
		}

		// Token: 0x02000057 RID: 87
		[Serializable]
		public class AnimatorEvent
		{
			// Token: 0x060003ED RID: 1005 RVA: 0x0002E028 File Offset: 0x0002C228
			public void Activate(bool pickUp)
			{
				if (this.animator != null)
				{
					if (pickUp)
					{
						this.animator.applyRootMotion = false;
					}
					this.Activate(this.animator);
				}
				if (this.animation != null)
				{
					this.Activate(this.animation);
				}
			}

			// Token: 0x060003EE RID: 1006 RVA: 0x0002E084 File Offset: 0x0002C284
			public void Activate(Animator animator)
			{
				if (this.animationState == string.Empty)
				{
					return;
				}
				if (this.resetNormalizedTime)
				{
					animator.CrossFade(this.animationState, this.crossfadeTime, this.layer, 0f);
				}
				else
				{
					animator.CrossFade(this.animationState, this.crossfadeTime, this.layer);
				}
			}

			// Token: 0x060003EF RID: 1007 RVA: 0x0002E0EC File Offset: 0x0002C2EC
			public void Activate(Animation animation)
			{
				if (this.animationState == string.Empty)
				{
					return;
				}
				if (this.resetNormalizedTime)
				{
					animation[this.animationState].normalizedTime = 0f;
				}
				animation[this.animationState].layer = this.layer;
				animation.CrossFade(this.animationState, this.crossfadeTime);
			}

			// Token: 0x04000299 RID: 665
			public const string empty = "";

			// Token: 0x0400029A RID: 666
			[Tooltip("The Animator component that will receive the AnimatorEvents.")]
			public Animator animator;

			// Token: 0x0400029B RID: 667
			[Tooltip("The Animation component that will receive the AnimatorEvents (Legacy).")]
			public Animation animation;

			// Token: 0x0400029C RID: 668
			[Tooltip("The name of the animation state.")]
			public string animationState;

			// Token: 0x0400029D RID: 669
			[Tooltip("The crossfading time.")]
			public float crossfadeTime = 0.3f;

			// Token: 0x0400029E RID: 670
			[Tooltip("The layer of the animation state (if using Legacy, the animation state will be forced to this layer).")]
			public int layer;

			// Token: 0x0400029F RID: 671
			[Tooltip("Should the animation always start from 0 normalized time?")]
			public bool resetNormalizedTime;
		}

		// Token: 0x02000058 RID: 88
		[Serializable]
		public class WeightCurve
		{
			// Token: 0x060003F1 RID: 1009 RVA: 0x000049E0 File Offset: 0x00002BE0
			public float GetValue(float timer)
			{
				return this.curve.Evaluate(timer);
			}

			// Token: 0x040002A0 RID: 672
			[Tooltip("The type of the curve (InteractionObject.WeightCurve.Type).")]
			public InteractionObject.WeightCurve.Type type;

			// Token: 0x040002A1 RID: 673
			[Tooltip("The weight curve.")]
			public AnimationCurve curve;

			// Token: 0x02000059 RID: 89
			[Serializable]
			public enum Type
			{
				// Token: 0x040002A3 RID: 675
				PositionWeight,
				// Token: 0x040002A4 RID: 676
				RotationWeight,
				// Token: 0x040002A5 RID: 677
				PositionOffsetX,
				// Token: 0x040002A6 RID: 678
				PositionOffsetY,
				// Token: 0x040002A7 RID: 679
				PositionOffsetZ,
				// Token: 0x040002A8 RID: 680
				Pull,
				// Token: 0x040002A9 RID: 681
				Reach,
				// Token: 0x040002AA RID: 682
				RotateBoneWeight,
				// Token: 0x040002AB RID: 683
				Push,
				// Token: 0x040002AC RID: 684
				PushParent,
				// Token: 0x040002AD RID: 685
				PoserWeight
			}
		}

		// Token: 0x0200005A RID: 90
		[Serializable]
		public class Multiplier
		{
			// Token: 0x060003F3 RID: 1011 RVA: 0x00004A01 File Offset: 0x00002C01
			public float GetValue(InteractionObject.WeightCurve weightCurve, float timer)
			{
				return weightCurve.GetValue(timer) * this.multiplier;
			}

			// Token: 0x040002AE RID: 686
			[Tooltip("The curve type to multiply.")]
			public InteractionObject.WeightCurve.Type curve;

			// Token: 0x040002AF RID: 687
			[Tooltip("The multiplier of the curve's value.")]
			public float multiplier = 1f;

			// Token: 0x040002B0 RID: 688
			[Tooltip("The resulting value will be applied to this channel.")]
			public InteractionObject.WeightCurve.Type result;
		}
	}
}
